package utils;

import org.apache.log4j.Logger;
import system.FileSystem;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

/**
 * @author waxijiang
 */
public class CommandUtils {
    /**
     * 日志
     */
    static Logger logger = Logger.getLogger(FileSystem.class);

    /**
     * 读取用户输入的命令
     *
     * @return 读取到的命令
     */
    public static String readCommand() {
        Scanner scanner = new Scanner(System.in);
        return scanner.nextLine().trim();
    }

    /**
     * 从用户输入的命令中提取要执行的命令
     *
     * @param command 用户输入的命令
     * @return 实际执行的命令
     */
    public static String getCommand(String command) {
        return command.split("\\s+")[0];
    }

    /**
     * 从用户输入的命令中提取要执行的命令的参数
     *
     * @param command 用户输入的命令
     * @return 指令命令的参数
     */
    public static String[] getParams(String command) {
        String[] source = command.split("\\s+");
        List<String> tmp = new ArrayList<String>(Arrays.asList(source));
        tmp.remove(0);
        return tmp.toArray(new String[tmp.size()]);
    }


    /**
     * 执行命令
     *
     * @param fileSystem 文件系统对象
     * @param command    命令
     * @param params     参数
     */
    public static void executeCommand(FileSystem fileSystem, String command, String... params) {
        Method method = matchCommand(command, params);

        Object[] args = null;
        if (params.length != 0) {
            args = new Object[params.length];
            System.arraycopy(params, 0, args, 0, params.length);
        }

        if (method != null) {
            try {
                if (args != null) {
                    method.invoke(fileSystem, args);
                } else {
                    method.invoke(fileSystem);
                }
            } catch (IllegalAccessException e) {
                logger.error(e.getStackTrace());
                Buffer.getInstance().write("args error");
            } catch (InvocationTargetException e) {
                logger.error(e.getStackTrace());
                Buffer.getInstance().write("method unknown error");
            }
        } else {
            Buffer.getInstance().write("command not found");
        }
    }

    /**
     * 根据名字和参数查找对应函数
     *
     * @param command 函数名
     * @param params  参数
     * @return 方法对象
     */
    public static Method matchCommand(String command, String... params) {
        // 构造参数列表的class数组
        Class<?>[] classes = new Class[params.length];
        for (int i = 0; i < params.length; i++) {
            classes[i] = params[i].getClass();
        }

        // 开始查找
        try {
            return FileSystem.class.getMethod(command, classes);
        } catch (NoSuchMethodException e) {
            return null;
        }
    }
}
